cmake_minimum_required(VERSION 3.18)
set(CMAKE_BUILD_TYPE Debug)
project(OpenKAI)

LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

OPTION(USE_CUDA "Use NVIDIA CUDA" OFF)
OPTION(USE_CHILITAGS "Use Chilitags" OFF)
OPTION(USE_DYNAMIXEL "Use Dynamixel" OFF)
OPTION(USE_GUI "Use GUI" OFF)
OPTION(USE_GLOG "Use glog" ON)
OPTION(USE_INFIRAY "Use InfiRay" OFF)
OPTION(USE_JETSON_INFERENCE "Use Jetson Inference" OFF)
OPTION(USE_LIVOX "Use Livox" OFF)
OPTION(USE_MATHGL "Use MathGL" OFF)
OPTION(USE_GUI "Use GUI" OFF)
OPTION(USE_OPEN3D "Use Open3D" OFF)
OPTION(USE_OPENCL "Use OpenCL" OFF)
OPTION(USE_OPENCV "Use OpenCV" OFF)
OPTION(USE_OPENCV_CONTRIB "Use OpenCV contribution" OFF)
OPTION(USE_ORB_SLAM "Use USE_ORB_SLAM" OFF)
OPTION(USE_QC "Use QC" OFF)
OPTION(USE_REALSENSE "Use Intel RealSense" OFF)
OPTION(USE_ROS "Use ROS" OFF)
OPTION(USE_TF-LITE "Use TensorFlow-Lite" OFF)
OPTION(USE_VZENSE "Use Vzense Nebular SDK" OFF)
OPTION(USE_XDYNAMICS "Use XDynamics SDK" OFF)
OPTION(USE_XARM "Use xArm" OFF)

OPTION(WITH_ACTUATOR "" OFF)
OPTION(WITH_ARDUPILOT "" OFF)
OPTION(WITH_AUTOPILOT_DRIVE "" OFF)
OPTION(WITH_APP_3DSCAN "" OFF)
OPTION(WITH_APP_CAMCALIB "" OFF)
OPTION(WITH_APP_DRONEBOX "" OFF)
OPTION(WITH_APP_GSV "" OFF)
OPTION(WITH_APP_LIVOXSCANNER "" OFF)
OPTION(WITH_APP_MEASUREMENT "" OFF)
OPTION(WITH_APP_ROPEWAYSCAN "" OFF)
OPTION(WITH_APP_ROBOTARM "" OFF)
OPTION(WITH_APP_ROVER "" OFF)
OPTION(WITH_APP_SWARMSEARCH "" OFF)
OPTION(WITH_APP_VZSCAN "" OFF)
OPTION(WITH_COMPUTE "" OFF)
OPTION(WITH_CONTROL "" ON)
OPTION(WITH_FILE "" ON)
OPTION(WITH_DETECTOR "" ON)
OPTION(WITH_DNN "" OFF)
OPTION(WITH_FILTER "" ON)
OPTION(WITH_GCS "" ON)
OPTION(WITH_IO "" ON)
OPTION(WITH_NAVIGATION "" ON)
OPTION(WITH_NET "" ON)
OPTION(WITH_3D "" OFF)
OPTION(WITH_PROTOCOL "" ON)
OPTION(WITH_ROS "" OFF)
OPTION(WITH_SCIENCE "" OFF)
OPTION(WITH_SENSOR "" ON)
OPTION(WITH_SLAM "" ON)
OPTION(WITH_STATE "" ON)
OPTION(WITH_SWARM "" ON)
OPTION(WITH_UI "" ON)
OPTION(WITH_UNIVERSE "" ON)
OPTION(WITH_VISION "" ON)

find_package(Eigen3 3.1.0 REQUIRED)
#find_package(Eigen3 3.1.0 REQUIRED NO_MODULE)

#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3")
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native")
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

#set(OpenKAI_definitions "-O3 -w -Wall -c -fmessage-length=0 -MMD -MP -std=c++17")
set(OpenKAI_definitions "-w -Wall -c -fmessage-length=0 -MMD -MP")
set(OpenKAI_libDir /usr/lib /usr/local/lib)
set(OpenKAI_include /usr/local/include /usr/include ${EIGEN3_INCLUDE_DIR})
set(OpenKAI_lib pthread boost_system uuid ${EIGEN3_LIBS} gsl gslcblas ncurses ssl crypto rt)

# File
file(GLOB_RECURSE OpenKAI_cpp src/main.cpp src/Base/*.cpp src/Base/*.cc src/Base/*.c)

file(GLOB_RECURSE Arithmetic_cpp src/Arithmetic/*.cpp src/Arithmetic/*.cc src/Arithmetic/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Arithmetic_cpp})

file(GLOB_RECURSE Config_cpp src/Config/*.cpp src/Config/*.cc src/Config/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Config_cpp})

file(GLOB_RECURSE IPC_cpp src/IPC/*.cpp src/IPC/*.cc src/IPC/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${IPC_cpp})

file(GLOB_RECURSE Primitive_cpp src/Primitive/*.cpp src/Primitive/*.cc src/Primitive/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Primitive_cpp})

file(GLOB_RECURSE Script_cpp src/Script/*.cpp src/Script/*.cc src/Script/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Script_cpp})

file(GLOB_RECURSE Startup_cpp src/Startup/*.cpp src/Startup/*.cc src/Startup/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Startup_cpp})

set(OpenKAI_cpp ${OpenKAI_cpp} src/UI/_Console.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/_FileBase.cpp)

# Optional modules
if(WITH_3D)
add_definitions(-DWITH_3D)
if(USE_OPEN3D)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/_GeometryBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/Mesh/_MeshStream.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PCstream.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PCframe.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PClattice.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PCfile.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PCmerge.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PCsend.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/_PCrecv.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCfilter/_PCtransform.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCfilter/_PCcrop.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCfilter/_PCremove.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCfilter/_PCdownSample.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCregistration/_PCregistCol.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCregistration/_PCregistICP.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/PointCloud/PCregistration/_PCregistGlobal.cpp)
if(USE_GUI)
set(OpenKAI_cpp ${OpenKAI_cpp} src/3D/_GeometryViewer.cpp)
endif()
endif()
endif()

if(WITH_ACTUATOR)
add_definitions(-DWITH_ACTUATOR)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_ActuatorBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_ArduServo.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_ActuatorSync.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_OrientalMotor.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_HYMCU_RS485.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/Articulated/_S6H4D.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_StepperGripper.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_SkydroidGimbal.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/Motor/_ZLAC8015.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/Motor/_ZLAC8015D.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/Motor/_ZDmotor.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/Motor/_DDSM.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/_Feetech.cpp)
file(GLOB_RECURSE Dependency_Feetech src/Dependency/Feetech/*.cpp src/Dependency/Feetech/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Dependency_Feetech})
if(USE_XARM)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Actuator/Articulated/_xArm.cpp)
endif()
endif()

if(WITH_ARDUPILOT)
add_definitions(-DWITH_ARDUPILOT)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_base.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_actuator.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_goto.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_move.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_RTH.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_relay.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_servo.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_takeoff.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_link.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AProver_drive.cpp)
if(WITH_SWARM)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_swarm.cpp)
endif()
if(WITH_SENSOR)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_distLidar.cpp)
endif()
if(USE_OPENCV)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_gcs.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_avoid.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_depthVision.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_land.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_mission.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_follow.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_videoStream.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_video.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_APcopter_photo.cpp)
if(WITH_APP_ROBOTARM)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AProver_picking.cpp)
endif()
endif() #opencv
if(WITH_NAVIGATION)
if(USE_REALSENSE)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_GPS.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Autopilot/ArduPilot/_AP_visionEstimate.cpp)
endif()
endif()
endif()

if(WITH_AUTOPILOT_DRIVE)
add_definitions(-DWITH_AUTOPILOT_DRIVE)
file(GLOB_RECURSE AutopilotDrive_cpp src/Autopilot/Drive/*.cpp src/Autopilot/Drive/*.cc src/Autopilot/Drive/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AutopilotDrive_cpp})
endif()

if(WITH_APP_CAMCALIB)
add_definitions(-DWITH_APP_CAMCALIB)
file(GLOB_RECURSE AppCamCalib_cpp src/Application/CamCalib/*.cpp src/Application/CamCalib/*.cc src/Application/CamCalib/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppCamCalib_cpp})
endif()

if(WITH_APP_DRONEBOX)
add_definitions(-DWITH_APP_DRONEBOX)
file(GLOB_RECURSE AppDroneBox_cpp src/Application/DroneBox/*.cpp src/Application/DroneBox/*.cc src/Application/DroneBox/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppDroneBox_cpp})
endif()

if(WITH_APP_GSV)
add_definitions(-DWITH_APP_GSV)
file(GLOB_RECURSE AppGSV_cpp src/Application/GSV/*.cpp src/Application/GSV/*.cc src/Application/GSV/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppGSV_cpp})
endif()

if(WITH_APP_MEASUREMENT AND USE_OPENCV)
add_definitions(-DWITH_APP_MEASUREMENT)
file(GLOB_RECURSE AppMeasurement_cpp src/Application/Measurement/*.cpp src/Application/Measurement/*.cc src/Application/Measurement/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppMeasurement_cpp})
endif()

if(WITH_APP_3DSCAN AND WITH_3D AND USE_OPEN3D AND USE_GUI)
add_definitions(-DWITH_APP_3DSCAN)
file(GLOB_RECURSE App3Dscan_cpp src/Application/3Dscan/*.cpp src/Application/3Dscan/*.cc src/Application/3Dscan/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${App3Dscan_cpp})
endif()

if(WITH_APP_VZSCAN AND USE_VZENSE AND WITH_3D AND USE_OPEN3D AND USE_GUI)
add_definitions(-DWITH_APP_VZSCAN)
file(GLOB_RECURSE AppVzScan_cpp src/Application/VzScan/*.cpp src/Application/VzScan/*.cc src/Application/VzScan/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppVzScan_cpp})
endif()

if(WITH_APP_LIVOXSCANNER AND USE_LIVOX AND WITH_3D AND USE_OPEN3D)
add_definitions(-DWITH_APP_LIVOXSCANNER)
file(GLOB_RECURSE AppLivoxScanner_cpp src/Application/LivoxScanner/*.cpp src/Application/LivoxScanner/*.cc src/Application/LivoxScanner/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppLivoxScanner_cpp})
endif()

#if(WITH_APP_ROPEWAYSCAN AND USE_VZENSE AND USE_LIVOX AND WITH_3D AND USE_OPEN3D)
if(WITH_APP_ROPEWAYSCAN)
add_definitions(-DWITH_APP_ROPEWAYSCAN)
#file(GLOB_RECURSE AppRopewayScan_cpp src/Application/RopewayScan/*.cpp src/Application/RopewayScan/*.cc src/Application/RopewayScan/*.c)
file(GLOB_RECURSE AppRopewayScan_cpp src/Application/RopewayScan/_RopewayScan.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppRopewayScan_cpp})
endif()

if(WITH_APP_ROBOTARM)
add_definitions(-DWITH_APP_ROBOTARM)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Application/RobotArm/_Sequencer.cpp)
if(USE_OPENCV)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Application/RobotArm/_PickingArm.cpp)
endif()
endif()

if(WITH_APP_ROVER)
add_definitions(-DWITH_APP_ROVER)
file(GLOB_RECURSE AppRover_cpp src/Application/Rover/*.cpp src/Application/Rover/*.cc src/Application/Rover/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppRover_cpp})
endif()

if(WITH_APP_SWARMSEARCH)
add_definitions(-DWITH_APP_SWARMSEARCH)
file(GLOB_RECURSE AppSwarmSearch_cpp src/Application/SwarmSearch/*.cpp src/Application/SwarmSearch/*.cc src/Application/SwarmSearch/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${AppSwarmSearch_cpp})
endif()

if(WITH_COMPUTE)
add_definitions(-DWITH_COMPUTE)
if(USE_OPENCL)
file(GLOB_RECURSE OCL_cpp src/Compute/*.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} ${OCL_cpp})
endif()
endif()

if(WITH_CONTROL)
add_definitions(-DWITH_CONTROL)
file(GLOB_RECURSE Control_cpp src/Control/*.cpp src/Control/*.cc src/Control/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Control_cpp})
endif()

if(WITH_DETECTOR)
add_definitions(-DWITH_DETECTOR)
if(USE_OPENCV)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_DetectorBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_Lane.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_YOLOv3.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_DNNclassifier.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_DNNtext.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_DepthSegment.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_IRLock.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_Line.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_OpenPose.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_HandKey.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_SSD.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_Thermal.cpp)
if(USE_OPENCV_CONTRIB)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_ArUco.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_MotionDetector.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Tracker/_TrackerBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Tracker/_SingleTracker.cpp)
endif()
if(USE_CUDA)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_Bullseye.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_Cascade.cpp)
endif()
if(USE_CHILITAGS)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Detector/_Chilitags.cpp)
endif()
endif()
endif()

if(WITH_DNN)
add_definitions(-DWITH_DNN)
if(USE_OPENCV)
if(USE_JETSON_INFERENCE)
file(GLOB_RECURSE JI_cpp src/DNN/JetsonInference/*.cpp src/DNN/JetsonInference/*.cc src/DNN/JetsonInference/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${JI_cpp})
endif()
if(USE_TF-LITE)
file(GLOB_RECURSE TFlite_cpp src/DNN/TensorFlowLite/*.cpp src/DNN/TensorFlowLite/*.cc src/DNN/TensorFlowLite/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${TFlite_cpp})
endif()
endif()
endif()

if(WITH_FILE)
add_definitions(-DWITH_FILE)
if(USE_OPENCV)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/Image/_PhotoTake.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/Image/_GPhotoTake.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/Image/_BBoxCutOut.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/Image/_CutOut.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/Image/_GDimgUploader.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/File/Video/_FrameCutOut.cpp)
endif()
endif()

if(WITH_FILTER)
add_definitions(-DWITH_FILTER)
file(GLOB_RECURSE Filter_cpp src/Filter/*.cpp src/Filter/*.cc src/Filter/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Filter_cpp})
endif()

if(WITH_GCS)
add_definitions(-DWITH_GCS)
file(GLOB_RECURSE GCS_cpp src/GCS/*.cpp src/GCS/*.cc src/GCS/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${GCS_cpp})
endif()

if(WITH_IO)
add_definitions(-DWITH_IO)
file(GLOB_RECURSE IO_cpp src/IO/*.cpp src/IO/*.cc src/IO/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${IO_cpp})
endif()

if(WITH_NAVIGATION)
add_definitions(-DWITH_NAVIGATION)
file(GLOB_RECURSE Dependency_nav src/Dependency/minmea.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Dependency_nav})
set(OpenKAI_cpp ${OpenKAI_cpp} src/Navigation/_NavBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Navigation/Coordinate.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Navigation/_GPS.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Navigation/_RTCM3.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Navigation/GeoGrid.cpp)
if(USE_REALSENSE)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Navigation/_RStracking.cpp)
endif()
endif()

if(WITH_NET)
add_definitions(-DWITH_NET)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Net/_Curl.cpp)
endif()

if(WITH_PROTOCOL)
add_definitions(-DWITH_PROTOCOL)
file(GLOB_RECURSE Protocol_cpp src/Protocol/*.cpp src/Protocol/*.cc src/Protocol/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Protocol_cpp})
file(GLOB_RECURSE Dependency_mdb src/Dependency/libmodbus/*.cpp src/Dependency/libmodbus/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Dependency_mdb})
file(GLOB_RECURSE Dependency_mvl src/Dependency/c_library_v2/*.cpp src/Dependency/c_library_v2/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Dependency_mvl})
endif()

if(WITH_ROS)
add_definitions(-DWITH_ROS)
file(GLOB_RECURSE ROS_cpp src/ROS/*.cpp src/ROS/*.cc src/ROS/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${ROS_cpp})
endif()

if(WITH_SCIENCE)
add_definitions(-DWITH_SCIENCE)
if(USE_QC)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Science/_QCbase.cpp)
endif()
if(USE_MATHGL)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Science/_ScienceBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Science/_FourierSeries.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Science/_Solver.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Science/_SolverBase.cpp)
endif()
endif()

if(WITH_SENSOR)
add_definitions(-DWITH_SENSOR)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Sensor/Distance/_DistSensorBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Sensor/Distance/_LeddarVu.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Sensor/Distance/_TOFsense.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Sensor/Distance/_BenewakeTF.cpp)
if(USE_LIVOX)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Sensor/LiDAR/Livox/_Livox.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Sensor/LiDAR/LivoxLidar.cpp)
endif()
endif()

if(WITH_SLAM)
add_definitions(-DWITH_SLAM)
if(USE_OPENCV)
if(USE_ORB_SLAM)
set(OpenKAI_cpp ${OpenKAI_cpp} src/SLAM/_ORB_SLAM.cpp)
endif()
endif()
endif()

if(WITH_STATE)
add_definitions(-DWITH_STATE)
file(GLOB_RECURSE State_cpp src/State/*.cpp src/State/*.cc src/State/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${State_cpp})
endif()

if(WITH_SWARM)
add_definitions(-DWITH_SWARM)
file(GLOB_RECURSE Swarm_cpp src/Swarm/*.cpp src/Swarm/*.cc src/Swarm/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Swarm_cpp})
endif()

if(WITH_UI)
add_definitions(-DWITH_UI)
set(OpenKAI_cpp ${OpenKAI_cpp} src/UI/_UIbase.cpp)
if(USE_OPENCV)
set(OpenKAI_cpp ${OpenKAI_cpp} src/UI/_GstOutput.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/UI/_WindowCV.cpp)
endif()
if(USE_GUI)
if(USE_OPEN3D)
set(OpenKAI_cpp ${OpenKAI_cpp} src/UI/O3DUI.cpp)
endif()
endif()
endif()

if(WITH_UNIVERSE)
add_definitions(-DWITH_UNIVERSE)
file(GLOB_RECURSE Universe_cpp src/Universe/*.cpp src/Universe/*.cc src/Universe/*.c)
set(OpenKAI_cpp ${OpenKAI_cpp} ${Universe_cpp})
endif()

if(WITH_VISION)
add_definitions(-DWITH_VISION)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_VisionBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/RGBD/_RGBDbase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/RGBD/_RGBDpointCloudBase.cpp)
if(USE_REALSENSE)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/RGBD/_RealSense.cpp)
endif()
if(USE_VZENSE)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/RGBD/_Vzense.cpp)
endif()
if(USE_XDYNAMICS)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/RGBD/_XDynamics.cpp)
endif()
if(USE_OPENCV)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/FrameBase.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/FrameGroup.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_Camera.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_SharedMemImg.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_VideoFile.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_ImgFile.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_GStreamer.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_GPhoto.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_DepthProj.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_DepthShow.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Morphology.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Mask.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Threshold.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Contrast.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Crop.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Depth2Gray.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Erode.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Grayscale.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_HistEqualize.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Invert.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_InRange.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Resize.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Remap.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/ImgFilter/_Rotate.cpp)
if(USE_INFIRAY)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_InfiRay.cpp)
endif()
if(USE_CUDA)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/FrameGPU.cpp)
set(OpenKAI_cpp ${OpenKAI_cpp} src/Vision/_DenseFlow.cpp)
endif()
endif()
endif()

# Dependencies
if(USE_CHILITAGS)
  add_definitions(-DUSE_CHILITAGS)
  set(OpenKAI_lib ${OpenKAI_lib} chilitags)
endif()

if(USE_CUDA)
  add_definitions(-DUSE_CUDA)
  set(CUDA_include "/usr/local/cuda/include" CACHE STRING "")
  set(OpenKAI_include ${OpenKAI_include} ${CUDA_include})
  set(CUDA_ARCH "72" CACHE STRING "")
  set(OpenKAI_lib ${OpenKAI_lib} opencv_cudawarping opencv_cudaobjdetect opencv_cudaarithm opencv_cudabgsegm opencv_cudaimgproc opencv_cudaoptflow opencv_cudastereo)
endif()

if(USE_DYNAMIXEL)
  add_definitions(-DUSE_DYNAMIXEL)
  set(OpenKAI_lib ${OpenKAI_lib} dxl_x64_cpp)
endif()

if(USE_GLOG)
  add_definitions(-DUSE_GLOG)
  set(OpenKAI_lib ${OpenKAI_lib} glog)
endif()

if(USE_GUI)
  add_definitions(-DUSE_GUI)
  set(OpenKAI_lib ${OpenKAI_lib} glfw GL m GLU GLEW)
endif()

if(USE_INFIRAY)
  add_definitions(-DUSE_INFIRAY)
endif()

if(USE_JETSON_INFERENCE)
  add_definitions(-DUSE_JETSON_INFERENCE)
  set(OpenKAI_include ${OpenKAI_include} "/usr/local/include/jetson-inference")
  set(OpenKAI_lib ${OpenKAI_lib} jetson-inference)
endif()

if(USE_LIVOX)
  add_definitions(-DUSE_LIVOX)
  set(OpenKAI_lib ${OpenKAI_lib} livox_sdk_static)
endif()

if(USE_MATHGL)
  add_definitions(-DUSE_MATHGL)
  set(OpenKAI_lib ${OpenKAI_lib} mgl mgl-fltk)
endif()

if(USE_OPEN3D)
  add_definitions(-DUSE_OPEN3D)
  set(Open3D_jsoncpp "/usr/include/jsoncpp" CACHE STRING "")
  set(OpenKAI_include ${OpenKAI_include} ${Open3D_jsoncpp})
  set(OpenKAI_lib ${OpenKAI_lib} Open3D)
endif()

if(USE_OPENCL)
  add_definitions(-DUSE_OPENCL)
  find_package(OpenCL REQUIRED)
  set(OpenKAI_include ${OpenKAI_include} ${OpenCL_INCLUDE_DIRS})
  set(OpenKAI_lib ${OpenKAI_lib} ${OpenCL_LIBRARIES})
endif()

if(USE_OPENCV)
  add_definitions(-DUSE_OPENCV)
  set(OpenCV_include "/usr/local/include/opencv4" CACHE STRING "")
  set(OpenCV_lib "/usr/local/lib" CACHE STRING "")
  set(OpenKAI_include ${OpenKAI_include} ${OpenCV_include})
  set(OpenKAI_libDir ${OpenKAI_libDir} ${OpenCV_lib})
  set(OpenKAI_lib ${OpenKAI_lib} opencv_core opencv_imgcodecs opencv_highgui opencv_imgproc opencv_videoio opencv_calib3d opencv_objdetect opencv_features2d opencv_dnn)
if(USE_FREETYPE)
  add_definitions(-DUSE_FREETYPE)
  set(OpenKAI_lib ${OpenKAI_lib} opencv_freetype)
endif()
endif()

if(USE_OPENCV_CONTRIB)
  add_definitions(-DUSE_OPENCV_CONTRIB)
  set(OpenKAI_lib ${OpenKAI_lib} opencv_xobjdetect opencv_tracking opencv_aruco)
endif()

if(USE_ORB_SLAM)
  find_package(Pangolin REQUIRED)
  add_definitions(-DUSE_ORB_SLAM)
  set(ORB_SLAM_root "/ORB_SLAM3" CACHE STRING "")
  set(OpenKAI_include ${OpenKAI_include} ${EIGEN3_INCLUDE_DIRS} ${Pangolin_INCLUDE_DIRS})
  set(OpenKAI_include ${OpenKAI_include} ${ORB_SLAM_root})
  set(OpenKAI_include ${OpenKAI_include} "${ORB_SLAM_root}/include" "${ORB_SLAM_root}/Thirdparty/Sophus" "${ORB_SLAM_root}/include/CameraModels")
  set(OpenKAI_libDir ${OpenKAI_libDir} "${ORB_SLAM_root}/lib")
  set(OpenKAI_lib ${OpenKAI_lib} ${Pangolin_LIBRARIES} ORB_SLAM3)
endif()

if(USE_REALSENSE)
  add_definitions(-DUSE_REALSENSE)
  set(OpenKAI_lib ${OpenKAI_lib} realsense2)
endif()

if(USE_TF-LITE)
  add_definitions(-DUSE_TF-LITE)
  set(TFlite_src "/tensorflow" CACHE STRING "")
  set(TFlite_flatbuffersInclude "/tensorflow/tensorflow/lite/tools/make/downloads/flatbuffers/include" CACHE STRING "")
  set(TFlite_abslInclude "/tensorflow/tensorflow/lite/tools/make/downloads/absl" CACHE STRING "")
  set(TFlite_lib "/tensorflow/tensorflow/lite/tools/make/gen/linux_aarch64/lib" CACHE STRING "")
  set(TFlite_flatbuffersLib "/tensorflow/tensorflow/lite/tools/make/downloads/flatbuffers/build" CACHE STRING "")
#  set(TFlite_build "/tensorflow/build" CACHE STRING "")
  set(OpenKAI_include
    ${OpenKAI_include}
    ${TFlite_src}
    ${TFlite_flatbuffersInclude}
    ${TFlite_abslInclude}
  )

  set(OpenKAI_libDir
    ${OpenKAI_libDir}
    ${TFlite_lib}
    ${TFlite_flatbuffersLib}
  )

  set(OpenKAI_lib
    ${OpenKAI_lib}
    tensorflow-lite
    flatbuffers
    dl
  )
endif()

if(USE_VZENSE)
  add_definitions(-DUSE_VZENSE)
  set(Vzense_include "NebulaSDK/Ubuntu18.04/Include" CACHE STRING "")
  set(Vzense_lib "NebulaSDK/Ubuntu18.04/Lib" CACHE STRING "")
  set(OpenKAI_include ${OpenKAI_include} ${Vzense_include})
  set(OpenKAI_libDir ${OpenKAI_libDir} ${Vzense_lib})
  set(OpenKAI_lib ${OpenKAI_lib} Nebula_api)
endif()

if(USE_XDYNAMICS)
  add_definitions(-DUSE_XDYNAMICS)
  set(XDynamics_include "OpenKAI_exm/XDynamics_SDK/linux/xdyn_streamer_SDK_linux_V3.4.3.8/include" CACHE STRING "")
  set(XDynamics_lib "OpenKAI_exm/XDynamics_SDK/linux/xdyn_streamer_SDK_linux_V3.4.3.8/lib" CACHE STRING "")
  set(OpenKAI_include ${OpenKAI_include} ${XDynamics_include})
  set(OpenKAI_libDir ${OpenKAI_libDir} ${XDynamics_lib})
  set(OpenKAI_lib ${OpenKAI_lib} xdyn_streamer xdyn_rgbd)
endif()

if(USE_XARM)
  add_definitions(-DUSE_XARM)
  set(OpenKAI_lib ${OpenKAI_lib} xarm)
endif()

# Setting specific lib here
link_directories(${OpenKAI_libDir})

if(USE_CUDA)
find_package(CUDA)
set(
	CUDA_NVCC_FLAGS
	${CUDA_NVCC_FLAGS}; 
    -O3 -gencode arch=compute_${CUDA_ARCH},code=sm_${CUDA_ARCH}
)
endif()

# Definitions
add_definitions(${OpenKAI_definitions})

# Exe
if(USE_CUDA)
cuda_add_executable(OpenKAI ${OpenKAI_cpp})
else()
add_executable(OpenKAI ${OpenKAI_cpp})
endif()

# C/C++ settings
include_directories(${OpenKAI_include})
target_link_libraries(OpenKAI ${OpenKAI_lib})
